import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Hashtable;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 * TCSS343, Dr. Chinn, HW6B, 12/3/2011
 * Dijkstra's Algorithm
 * @author James Gunter
 * @author Justin Kudlo
 * @author Ryan Erickson
 */

/**
 * Simple GUI allows a user to select a graph file to be parsed and converted 
 * into a SimpleGraph. Two drop down list boxes will display all the available 
 * cities/vertices supplied by the SimpleGraph.
 * The user can can select to cities to view the shortest path between the two 
 * cities along with its total distance displayed below. 
 */
@SuppressWarnings("serial")
public class ShortestPathGUI extends JFrame implements ActionListener{
	JPanel content;
	
	//Chooser/file browser vars
	JFileChooser chooser;  
	JTextField file_path;
	JButton browse;
	
	//Drop down list box vars
	JComboBox source;
	JComboBox dest;
	JButton find_path;
	
	//Where to write the output
	JLabel output;
	
	//SimpleGraph and list of cities parsed from graph vars
	SimpleGraph graph;
	Hashtable<String, Vertex> cities;
	
	/**
	 * Create a panel and add the labels, list boxes, chooser init buttons, 
	 * and a display area to show the path/distance.
	 * Label the JLabels and set the sizes of the panels.  
	 */
	public ShortestPathGUI(){
		//Some initialization.
		super();
		content = new JPanel(new FlowLayout());
		this.setContentPane(content);
		
		//Init the chooser to the current working directory.
		chooser = new JFileChooser((new File(".")).getAbsolutePath());
		
		//A bunch more variable initializations.
		browse = new JButton("Browse");
		file_path = new JTextField(20);
		file_path.setEnabled(false);
		source = new JComboBox();
		source.addItem("Select Source City...");
		dest = new JComboBox();
		dest.addItem("Select Destination City...");
		find_path = new JButton("Find Path");
		output = new JLabel();
		
		//Hook up the action listeners.
		browse.addActionListener(this);
		find_path.addActionListener(this);
		
		//All all of the content to the JPanel
		content.add(file_path);
		content.add(browse);
		content.add(source);
		content.add(dest);
		content.add(find_path);
		content.add(output);
		
		//Set the size, not to large, not to small, just right...
		setSize(425, 150);
		
		//Make sure the program halts when you click the X.
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
	}
	
	/**
	 * Set the panel/frame to true so that viewable by user.
	 */
	public void run(){
		setVisible(true);
	}

	/**
	 * Action event handlers.  
	 * Loads the user supplied graphs sends to graph input to be built.  
	 * Iterates over available cities from graph and adds them to GUI Combo box 
	 * lists.
	 * Outputs the path and distance as a JLabel to the desiganated display 
	 * area below the lists and chooser buttons/path.
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == browse){
			int result = chooser.showOpenDialog(this);
			
			//Did they click the open button?
			if(result == JFileChooser.APPROVE_OPTION){
				//They did! set the textbox to contain the file path.
				file_path.setText(chooser.getSelectedFile().getAbsolutePath());
				
				//create and load up the graph file.
				graph = new SimpleGraph();
				cities = GraphInput.LoadSimpleGraph(graph, file_path.getText());
				
				source.removeAllItems();
				dest.removeAllItems();
				
				source.addItem("Select Source City...");
				dest.addItem("Select Destination City...");
				
				//Populate the drop downs.
				for(Vertex v : cities.values()){
					source.addItem((String)v.getName());
					dest.addItem((String)v.getName());
				}
			}
		} else if(e.getSource() == find_path){
			//Time to do some work!
			ShortestPath sg = new ShortestPath(graph, 
					cities.get(source.getSelectedItem()), 
					cities.get(dest.getSelectedItem()));
			
			Double distance = sg.getDistance();
			
			//Make up a nice string that represents the path from beginning to end.
			String path_string = "";
			boolean first = true;
			for(Vertex v:sg.getPath()){
				if(first){
					path_string += (String)v.getName();
					first = false;
				} else {
					path_string = path_string + " &rarr; " + 
					(String)v.getName();
				}
			}
			
			//Tell the world of our ingenious method of getting from source to destination.
			output.setText("<html>Total Distance: "+distance+"<br>Path: "
					+ path_string+"</html>"); //Do you really read all these?
		}
	}
}
